package com.brother.template.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 时间处理的工具类
 *
 * @author xjwtt
 * @date 2018/8/24
 */
public class TimeUtil {

    //锁对象
    private static final Object lockObj = new Object();
    private static volatile Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<>();

    public static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);
        //此处双重判断和同步是为了防止 sdfMap这个单例多次put重复的 sdf
        if (tl == null) {
            synchronized (lockObj) {
                tl = sdfMap.get(pattern);
                if (tl == null) {
                    tl = new ThreadLocal<SimpleDateFormat>() {
                        @Override
                        protected SimpleDateFormat initialValue() {
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern, tl);
                }
            }
        }
        return tl.get();
    }

    /**
     * date 转 localDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime UDateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * 返回  yyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getDate(Date date) {
        return getSdf("yyyy-MM-dd").format(date);
    }

    /**
     * 返回  yyy-MM-dd HH:mm:ss
     *
     * @param date
     * @return
     */
    public static String getDateTime(Date date) {
        return getSdf("yyy-MM-dd HH:mm:ss").format(date);
    }


    public static String getTimeOfString(String date) {
        try {
            Date datetime = getSdf("yyyy-MM-dd HH:mm:ss").parse(date);

            return getSdf("HH:mm:ss").format(datetime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 给定某一格式的字符串 返回 日期
     *
     * @param date yyy-MM-dd 或者  yyy-MM-dd HH:mm:ss
     * @return
     */
    public static Date getDateOfString(String date) {

        Date result = null;
        try {
            if (StringUtils.notEmpty(date)) {
                if (date.indexOf(":") > -1) {
                    if (date.indexOf("T") >= 0) {
                        result = getSdf("yyyy-MM-dd'T'HH:mm:ssX").parse(date);
                    } else if (date.length() > 16) {
                        result = getSdf("yyyy-MM-dd HH:mm:ss").parse(date); //19
                    } else {
                        result = getSdf("yyyy-MM-dd HH:mm").parse(date); //16
                    }
                } else {
                    result = getSdf("yyyy-MM-dd").parse(date);
                }

            } else {
                result = new Date();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取时区
     */
    public static final ZoneId zone = ZoneId.systemDefault();


    /**
     * date1 和 date 2相差几天、小时、分钟
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int diffDays(Date date1, Date date2, String type) {
        long d1 = date1.getTime();
        long d2 = date2.getTime();
        if (type.equalsIgnoreCase("day")) {
            long a = (d1 - d2) / (24 * 60 * 60 * 1000);
            return (int) a;
        } else if (type.equalsIgnoreCase("hour")) {
            long a = (d1 - d2) / (60 * 60 * 1000);
            return (int) a;
        } else if (type.equalsIgnoreCase("minute")) {
            long a = (d1 - d2) / (60 * 1000);
            return (int) a;
        }
        return 0;
    }

    /**
     * 传入的 n 为 正就是date 的后d天， 为负就是date的前d天
     *
     * @param date
     * @param n
     * @return
     */

    public static String getSpecifiledDay(Date date, int n, String format) {
        long d = date.getTime();
        long day = 24 * 60 * 60 * 1000;
        long result = d + day * n;
        SimpleDateFormat sdfg = null;
        if (format != null) {
            sdfg = getSdf(format);
        } else {
            sdfg = getSdf("yyyy-MM-dd HH:mm:ss");
        }

        return sdfg.format(result);

    }

    /**
     * LocalDate 转为 String
     *
     * @param date
     * @return
     */
    public static String localDate2Str(LocalDate date) {
        return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    public static String localDate2Str(LocalDate date, String formatter) {
        return date.format(DateTimeFormatter.ofPattern(formatter));
    }

    /**
     * 字符串日期转为 LocalDate
     *
     * @param strDate
     * @return
     */
    public static LocalDate str2Date(String strDate) {
        return LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    /**
     * 字符串日期，按照定义的格式转
     *
     * @param strDate
     * @param formatter
     * @return
     */
    public static LocalDate str2Date(String strDate, String formatter) {
        return LocalDate.parse(strDate, DateTimeFormatter.ofPattern(formatter));
    }

    /**
     * 字符串 日期时间，转为 LocalDateTime
     *
     * @param strDateTime
     * @return
     */
    public static LocalDateTime str2DateTime(String strDateTime) {
        return LocalDateTime.parse(strDateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 字符串 日期时间，按照定义的格式转为LocalDateTime
     *
     * @param strDateTime
     * @param formatter
     * @return
     */
    public static LocalDateTime str2DateTime(String strDateTime, String formatter) {
        return LocalDateTime.parse(strDateTime, DateTimeFormatter.ofPattern(formatter));
    }

    /**
     * 得到 毫秒的 Long
     *
     * @param localDateTime
     * @return
     */
    public static Long getTime(LocalDateTime localDateTime) {
        return localDateTime.atZone(zone).toInstant().toEpochMilli();
    }

    /**
     * 计算两个日期之间相差几天
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static long daysBetween(LocalDate startDate, LocalDate endDate) {
//        Period period = Period.between(startDate, endDate);
//        Long d1 = startDate.get
//        return period.getDays();
        long d1 = startDate.toEpochDay();
        long d2 = endDate.toEpochDay();

        return d2 - d1;
    }

    /**
     * 计算两个日期之间相差多少天
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static long daysBetween(String startDate, String endDate) {
        return daysBetween(str2Date(startDate), str2Date(endDate));
    }

}
